class IUP_COLOR_BROWSER
-- Creates an element for selecting a color. The selection is done using a 
-- cylindrical projection of the RGB cube. The transformation defines a 
-- coordinate color system called HSI, that is still the RGB color space but 
-- using cylindrical coordinates.
--
-- H is for Hue, and it is the angle around the RGB cube diagonal starting at 
-- red (RGB=255 0 0).
--
-- S is for Saturation, and it is the normal distance from the color to the 
-- diagonal, normalized by its maximum value at the specified Hue. This also 
-- defines a point at the diagonal used to define I.
--
-- I is for Intensity, and it is the distance from the point defined at the 
-- diagonal to black (RGB=0 0 0). I can also be seen as the projection of the 
-- color vector onto the diagonal. But I is not linear, see Notes below.
--
-- For a dialog that simply returns the selected color, you can use function 
-- IUP_GET_COLOR or IUP_COLOR_DIALOG.
--
-- Notes:
--
-- When the control has the focus the keyboard can be used to change the color 
-- value. Use the arrow keys to move the cursor inside the SI triangle, and use 
-- Home(0), PageUp, PageDn and End(180) keys to move the cursor inside the Hue 
-- circle.
--
-- The Hue in the HSI coordinate system defines a plane that it is a triangle 
-- in the RGB cube. But the maximum saturation in this triangle is different 
-- for each Hue because of the geometry of the cube. In ColorBrowser this point 
-- is fixed at the center of the I axis. So the I axis is not completely 
-- linear, it is linear in two parts, one from 0 to 0.5, and another from 0.5 
-- to 1.0. Although the selected values are linear specified you can notice 
-- that when Hue is changed the gray scale also changes, visually compacting 
-- values above or below the I=0.5 line according to the selected Hue.
--
-- This is the same HSI specified in the IM toolkit, except for the non 
-- linearity of I. This non linearity were introduced so a simple triangle 
-- could be used to represent the SI plane.
	
inherit
	IUP_WIDGET
		redefine
			execute_change,
			execute_drag,
			execute_valuechanged
		end
	IUP_WIDGET_INTERNALS
	IUP_WIDGET_ACTIVE
	IUP_WIDGET_BGCOLOR
	IUP_WIDGET_FONT
	IUP_WIDGET_POSITION
	IUP_WIDGET_MAXMIN_SIZE
	IUP_WIDGET_WID
	IUP_WIDGET_TIP
	IUP_WIDGET_SIZE
	IUP_WIDGET_ZORDER
	IUP_WIDGET_VISIBLE
	IUP_WIDGET_RASTERSIZE
		redefine
			set_raster_size
		end
	IUP_WIDGET_EXPAND
		redefine
			set_expand
		end

create {ANY}
	color_browser

feature {ANY}

	color_browser
		local
			a_color_browser: POINTER
		do
			a_color_browser := int_color_browser

			set_widget(a_color_browser)
		end

	-- Attributes

	set_expand (type: STRING)
		-- The default value is "False".
		do
			Precursor (type)
		end

	set_raster_size (width: INTEGER; height: INTEGER)
		-- (non inheritable): the initial size is "181x181".
		do
			Precursor (width, height)
		end

	set_automatic_layout
		-- Set to allow the automatic layout use smaller values.
		do
			iup_open.set_attribute_null(Current, "RASTERSIZE")
		end

	set_value_rgb (red, green, blue: INTEGER)
		-- The color value in RGB coordinates and optionally alpha. It is used as 
		-- the initial value and contains the selected value if the user pressed 
		-- the Ok button. Format: "R G B A". Each component range from 0 to 255.
		do
			iup_open.set_attribute(Current, "RGB", rgb_to_string(red,
																				  green,
																				  blue))
		end

	get_value_rgb: TUPLE[INTEGER, INTEGER, INTEGER]
		-- Return the selected value.
		do
			Result := iup_open.get_rgb(Current, "RGB")
		end

	set_value_hsi (h, s, i: REAL_64)
		-- (non inheritable): the color selected in the control, in the "h s i"
		-- format; h, s and i are floating point numbers ranging from 0-360, 0-1 
		-- and 0-1 respectively.
		do
			iup_open.set_attribute(Current, "HSI", hsi_real_to_string(h, s, i))
		end

	get_value_hsi: TUPLE[REAL_64, REAL_64, REAL_64]
		-- Return the selected value.
		do
			Result := iup_open.get_hsi_real(Current, "HSI")
		end

	-- Callbacks

	set_cb_change (act: FUNCTION[TUPLE[IUP_COLOR_BROWSER, INTEGER, INTEGER, INTEGER], STRING])
		-- Called when the user releases the left mouse button over the control, 
		-- defining the selected color.
		--
		-- ih: identifier of the element that activated the event.
		-- red, green, blue: color value.
		local
			operation: INTEGER
		do
			cb_change := act

			if cb_change /= Void then
				operation := 1
			else
				operation := 0
			end
			
			iup_open.set_callback (Current, "CHANGE_CB", "NONEEDED", operation)
		end

	set_cb_drag (act: FUNCTION[TUPLE[IUP_COLOR_BROWSER, INTEGER, INTEGER, INTEGER], STRING])
		-- Called several times while the color is being changed by dragging the 
		-- mouse over the control.
		--
		-- ih: identifier of the element that activated the event.
		-- red, green, blue: color value.
		local
			operation: INTEGER
		do
			cb_drag := act

			if cb_drag /= Void then
				operation := 1
			else
				operation := 0
			end
			
			iup_open.set_callback (Current, "DRAG_CB", "NONEEDED", operation)
		end

	set_cb_value_changed (act: FUNCTION[TUPLE[IUP_COLOR_BROWSER], STRING])
		-- Called after the value was interactively changed by the user. It is 
		-- called whenever a CHANGE_CB or a DRAG_CB would also be called, it is 
		-- just called after them.
		--
		-- ih: identifier of the element that activated the event.
		local
			operation: INTEGER
		do
			cb_valuechanged := act

			if cb_valuechanged /= Void then
				operation := 1
			else
				operation := 0
			end
			
			iup_open.set_callback (Current, "VALUECHANGED_CB", "NONEEDED", operation)
		end

feature {IUP}

	execute_change (red, green, blue: INTEGER): STRING
		do
			Result := cb_change.item([Current, red, green, blue])
		end

	execute_drag (red, green, blue: INTEGER): STRING
		do
			Result := cb_drag.item([Current, red, green, blue])
		end

	execute_valuechanged: STRING
		do
			Result := cb_valuechanged.item([Current])
		end	

feature {}

	-- Callbakcs

	cb_change: FUNCTION[TUPLE[IUP_COLOR_BROWSER, INTEGER, INTEGER, INTEGER], STRING]
	cb_drag: FUNCTION[TUPLE[IUP_COLOR_BROWSER, INTEGER, INTEGER, INTEGER], STRING]
	cb_valuechanged: FUNCTION[TUPLE[IUP_COLOR_BROWSER], STRING]

	-- Internals
	
	int_color_browser: POINTER
		external "plug_in"
      alias "{
         location: "${sys}/plugins"
         module_name: "iup"
         feature_name: "IupColorBrowser()"
         }"
      end

end -- class IUP_COLOR_BROWSER

-- The MIT License (MIT)

-- Copyright (c) 2019 by German A. Arias

-- Permission is hereby granted, free of charge, to any person obtaining a copy
-- of this software and associated documentation files (the "Software"), to deal
-- in the Software without restriction, including without limitation the rights
-- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-- copies of the Software, and to permit persons to whom the Software is
-- furnished to do so, subject to the following conditions:
--
-- The above copyright notice and this permission notice shall be included in 
-- all copies or substantial portions of the Software.
--
-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-- SOFTWARE.
